#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
############################################################################
#    Coopyright (C) 2009 by:                                               #
#    Olivier Palombi (olivier.palombi 'at' inrialpes.fr)                   #
#                                                                          #
#    This program is free software; you can redistribute it and#or modify  #
#    it under the terms of the GNU General Public License as published by  #
#    the Free Software Foundation; either version 2 of the License, or     #
#    (at your option) any later version.                                   #
#                                                                          #
#    This program is distributed in the hope that it will be useful,       #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#    GNU General Public License for more details.                          #
#                                                                          #
#    You should have received a copy of the GNU General Public License     #
#    along with this program; if not, write to the                         #
#    Free Software Foundation, Inc.,                                       #
#    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
############################################################################

version_name="ASFX 0.1"
import sys, os, time#, vtk

if sys.platform.startswith('linux'):
	sys.path.append(sys.path[0] + "/../../")
	sys.path.append(sys.path[0] + "/../ui")
if sys.platform.startswith('win'):
	sys.path.append(sys.path[0] + "\\..\\..")
	sys.path.append(sys.path[0] + "\\..\\ui")

from PyQt4 import QtGui, QtCore
from libASFX import *
from ASFXTreeWidget import *
#from Q4VTKRenderWindowInteractor import QVTKRenderWindowInteractor
from Ui_main import Ui_MainWindow
from dialog_login import Dialog_login
from dialog_new_acquisition import *
from dialog_AE_translation import dialog_AE_translation
from dialog_new_attribute_type import dialog_new_attribute_type
from dialog_db_check import *



class myCFAppli(QtGui.QMainWindow, Ui_MainWindow):

	def __init__(self,sqlserver):
		super(myCFAppli,self).__init__()     
		
		#This string contains a platform identifier
		platform = sys.platform
		
		# Configure l'interface utilisateur
		self.setupUi(self)
		self.noteEdited_ = False
		
		
		# Initialization of ontology objet
		## SQL serveur to the Database
		self.sqlserver = sqlserver 
 
		## Update combobox of Ontology (db)
		self.firstpass = True
		self.ignore_db_index_change = True
		for r in ['Human diseases','Human anatomy (2010)','Human anatomy (2011)']:
			self.comboBox_db.addItem ( QtCore.QString.fromUtf8(r))
		self.ignore_db_index_change = False
		
		# Show the AE Tree
		self.gridLayout.removeWidget( self.frame_temp_tree_AE)
		self.frame_temp_tree_AE.hide()
		
		self.init_ontology(self.comboBox_db.currentText(),self.sqlserver)
		#if self.libmyCF.ontology.all_AEs[2].isA({"Bone organ"}) :
		#	print "isAChilOf function works"

		
	def init_ontology( self,ontology, sqlserver):
		self.libmyCF = libmyCF( ontology, sqlserver)		
		title =  QtCore.QString('Ontology: ') + QtCore.QString( ontology)
		self.tabWidget.setTabText(0,title)
		print("MySQL database retrieved")
		
		#print self.libmyCF.connector.access_mode
		if not self.libmyCF.connector.access_mode == "write":
			self.action_IOdb.setEnabled(False)
        
		#refresh AE tree
		self.treeWidget_AE = MyCFTreeWidget(self, self.libmyCF)
		self.treeWidget_AE.setMinimumSize(QtCore.QSize(500,574))
		self.treeWidget_AE.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)      
		self.gridLayout.addWidget(self.treeWidget_AE, 1, 0, 4, 2)
        
        # NOT NEEDED : the tree is refresh when the combobox is updated : it triggers the index_change signal and so the refreshTree function 
		#self.treeWidget_AE.refreshTree(1) #self.comboBox_relation_type.itemData(self.comboBox_relation_type.currentIndex()).toInt()[0]
		#print("mCFTree build")
        
		
		#Update combobox of relations
		self.comboBox_relation_type.clear()
		#self.comboBox_relation_type.isEditable()
		self.take_account_of_index_change = True #needed for the function on_comboBox_relation_type_currentIndexChanged
												  #if not set false at the initiation, the tree is refresh when building the combobox_relation_type, whenever the tree has been already build before the combobox
		index = 1
		for relation_type_key in self.libmyCF.ontology.all_relations_type:  
			r = self.libmyCF.ontology.all_relations_type[relation_type_key]
			self.comboBox_relation_type.insertItem (index, QtCore.QString.fromUtf8(r.name), QtCore.QVariant(r.relation_type_id))
			index += 1    
		if self.libmyCF.connector.access_mode == "write" :
			self.comboBox_relation_type.insertItem (index, QtGui.QIcon(":/icons/db_add.png"),QtCore.QString.fromUtf8("Add a new relation type..."))
			self.comboBox_relation_type.insertSeparator(index)
		self.previous_index = 1 #if the dialog "new relationtype" is selected but not executed (no new relation type), the combobox returns to the previous index
		self.take_account_of_index_change = True
        
        #Connections
		self.connect( self.treeWidget_AE, QtCore.SIGNAL("currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)"), self.on_treeWidget_AE_currentItemChanged)
        
        
		#Information about current database connection 
		if self.firstpass is not True:
			QtGui.QMessageBox.information( self, version_name, unicode( "Current database is: " + self.libmyCF.ontology.name))
		self.firstpass = False
		

	@QtCore.pyqtSignature("int")
	def on_comboBox_db_currentIndexChanged(self,index):
		if not self.ignore_db_index_change :
			self.init_ontology(self.comboBox_db.currentText(),self.sqlserver)


	@QtCore.pyqtSignature("int")
	def on_comboBox_relation_type_currentIndexChanged(self,index):
		if self.take_account_of_index_change :
			if not self.comboBox_relation_type.currentText() == "Add a new relation type..." :
				key = self.comboBox_relation_type.itemData(index).toInt()[0]
				#if self.treeWidget_AE is not None:
				self.treeWidget_AE.clear()
				self.treeWidget_AE.refreshTree(key)
				print("mCFTree build\n")
				self.previous_index = self.comboBox_relation_type.currentIndex()
			else :
				new_rel_type_dia = dialog_new_relation_type(self,self.libmyCF.ontology)
				if not new_rel_type_dia.exec_(): #no relation type has been created, the item "add a new relation type" is selected and has to be replaced by the previous item
					self.take_account_of_index_change = False #else the index change signal is triggered, and the tree is refreshed, for nothing
					self.comboBox_relation_type.setCurrentIndex(self.previous_index)
					self.take_account_of_index_change = True
                     
				else : #a new relation type is created, the new tree is displayer
					rel_type_id = new_rel_type_dia.rel_type_id
					name = new_rel_type_dia.name
					if rel_type_id != None :
						index = self.comboBox_relation_type.currentIndex()
						# The insertion of an item in the combobox triggers the signal of changed index. The current function is called again
						# and since the index is the index of "add new relation type...", it opens the dialog again and again
						self.take_account_of_index_change = False
						self.comboBox_relation_type.insertItem (int(index-1), QtCore.QString.fromUtf8(name), QtCore.QVariant(rel_type_id))
						self.take_account_of_index_change = True
						self.comboBox_relation_type.setCurrentIndex(int(index-1))
						#pass

	@QtCore.pyqtSignature("bool")
	def on_action_About_Qt_triggered(self):
		QtGui.QMessageBox.aboutQt ( self, QtCore.QString("about?"))
        

	@QtCore.pyqtSignature("bool")
	def on_action_About_myCorporisFabrica_triggered(self):
		QtGui.QMessageBox.about(self, self.tr("About this software."), 
							QtCore.QString(self.tr("<p>Cette application en Python permet la gestion de la base de connaissances medicales : "+version_name
														+"</p><p>Auteurs: Olivier Palombi, Guillaume Bousquet, David Jospin</p> <p>Date de creation: Juin 2008</p>")))

	@QtCore.pyqtSignature("bool")
	def on_action_Check_db_integrity_triggered(self):
		#from dialog_db_check import *
		
        #(messages, error, summary) = self.libmyCF.ontology.check_db_integrity()
		#error_report = QtCore.QString("") #string type is immutable, using the QString type allows to use method "append"
		#for message in messages :
		#	error_report.append(message)
		
        #if error :
		#	QtGui.QMessageBox.warning( self,"Check myCF database", QtCore.QString(error_report))
		#else :
		#	QtGui.QMessageBox.information( self,"Check myCF database", QtCore.QString(error_report))
		dia_db_check = dialog_db_check(self,self.libmyCF.ontology)#,error_report, error, summary)
		#dia_db_check.open()
		#dia_db_check.show()
		dia_db_check.exec_()
        
	@QtCore.pyqtSignature("bool")
	def on_actionExport_to_SOFA_triggered(self):
		if sys.platform.startswith('linux'):
			print ("Export to SOFA:")
			os.execvp('/home/olivier/MesDocuments/Travaux/workspace/fabrica-tools/src/myCF_to_Sofa', ("python","main.py"))
		
	@QtCore.pyqtSignature("bool")
	def on_action_Find_AE_triggered(self):
		from dialog_find_AE import dialog_find_AE

		new_dia_find = dialog_find_AE(self)

		if new_dia_find.exec_():
			name_AE = new_dia_find.comboBox_find_AE.currentText()
			AE = self.treeWidget_AE.findItem(name_AE)
			if AE:            
				# First Solution :
				#self.treeWidget_AE.reccur_collapse(self.treeWidget_AE.itemAt(0,0))
				#self.treeWidget_AE.setCurrentItem(self.treeWidget_AE.itemAt(0,0))
				#self.treeWidget_AE.setCurrentItem(AE)
				#self.treeWidget_AE.expandItem(self.treeWidget_AE.currentItem())
                
				# Second Solution :
				self.treeWidget_AE.reccur_collapse(self.treeWidget_AE.itemAt(0,0))
				self.treeWidget_AE.reccur_expand_inverse(AE)
				self.treeWidget_AE.setCurrentItem(AE)
				
		
	@QtCore.pyqtSignature("bool")
	def on_action_IOdb_triggered(self):
		from dialog_export import dialog_export

		new_dia_export = dialog_export(self)
		#if new_dia_export.exec_():
		new_dia_export.exec_()
		
			
		
	def translate_mcfTree(self,translation):	
		(error_type,error_report) = self.libmyCF.ontology.check_mycfTree_translation(translation)
		if error_type == 0 :### 0 : No error
			
			self.libmyCF.ontology.set_translation(translation)
						
			self.treeWidget_AE = MyCFTreeWidget(self, self.libmyCF)
			self.treeWidget_AE.setMinimumSize(QtCore.QSize(500,574))         
			self.gridLayout.addWidget(self.treeWidget_AE, 1, 0, 4, 2)
			self.treeWidget_AE.refreshTree(self.comboBox_relation_type.itemData(self.comboBox_relation_type.currentIndex()).toInt()[0])
			
			#if self.libmyCF.connector.access_mode == "read":
			#	QtGui.QMessageBox.information(self,"myCF information","You can not edit the ontology in this translation. You are in read mode only")
        	#	return True
			
			#Connections
			self.connect( self.treeWidget_AE, QtCore.SIGNAL("currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)"), self.on_treeWidget_AE_currentItemChanged)
        
			return True

		if error_type == 1 :## 1 : attribute type for the selected language does not exist
			QtGui.QMessageBox.warning(self,"myCF error",error_report)
			if self.libmyCF.connector.access_mode == "write":
				new_att_type_dia = dialog_new_attribute_type(self,self.libmyCF.ontology)
				if new_att_type_dia.exec_():
					#retrieve the name, type and value of the new type attribute from the dialog
					name = new_att_type_dia.name
					type = new_att_type_dia.type
					definition = new_att_type_dia.definition
					example = new_att_type_dia.example 
					#Create he attribute type in the database and the local ontology and retrieve its ID.
					newAtt = self.libmyCF.ontology.add_attribute_type( name,type,definition,example)
					QtGui.QMessageBox.information(self,"myCF information","You should now be able to start translations.")
				else :
					QtGui.QMessageBox.warning(self,"myCF information","The selected translation has not been created.")
			return False

		if error_type == 2 :## 2 : missing translation
			QtGui.QMessageBox.information(self,"myCF error",error_report)
			if self.libmyCF.connector.access_mode == "write" :
				translation_dia = dialog_AE_translation(self,self.libmyCF.ontology,translation) 
				if translation_dia.exec_():
					if translation_dia.all_translated : 
						self.translate_mcfTree(translation) # recall the function, but this time the error_type will be 0
			return False
		
	@QtCore.pyqtSignature("bool")
	def on_actionFrench_triggered(self):
		translation = "French translation"
		if self.translate_mcfTree(translation) :
			self.actionEnglish.setChecked(False)
			self.actionLatin.setChecked(False)
			self.actionGerman.setChecked(False)
			self.actionFrench.setChecked(True)
		else :
			self.actionFrench.setChecked(False)
			
		
	@QtCore.pyqtSignature("bool")
	def on_actionGerman_triggered(self):
		translation = "German translation"
		if self.translate_mcfTree(translation) :
			self.actionEnglish.setChecked(False)
			self.actionLatin.setChecked(False)
			self.actionGerman.setChecked(True)
			self.actionFrench.setChecked(False)
		else :
			self.actionGerman.setChecked(False)
						
	@QtCore.pyqtSignature("bool")
	def on_actionLatin_triggered(self):
		translation = "Latin translation"
		if self.translate_mcfTree(translation) :
			self.actionEnglish.setChecked(False)
			self.actionLatin.setChecked(True)
			self.actionGerman.setChecked(False)
			self.actionFrench.setChecked(False)
		else :
			self.actionLatin.setChecked(False)
		
	@QtCore.pyqtSignature("bool")
	def on_actionEnglish_triggered(self):
		translation = "English translation"
		self.actionEnglish.setChecked(True)
		self.actionLatin.setChecked(False)
		self.actionGerman.setChecked(False)
		self.actionFrench.setChecked(False)
		self.libmyCF.ontology.set_translation(translation)
		self.treeWidget_AE = MyCFTreeWidget(self, self.libmyCF)
		self.treeWidget_AE.setMinimumSize(QtCore.QSize(500,574))         
		self.gridLayout.addWidget(self.treeWidget_AE, 1, 0, 4, 2)
		self.treeWidget_AE.refreshTree(self.comboBox_relation_type.itemData(self.comboBox_relation_type.currentIndex()).toInt()[0])
		#Connections
		self.connect( self.treeWidget_AE, QtCore.SIGNAL("currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)"), self.on_treeWidget_AE_currentItemChanged)
        	
		
		
					
	

	@QtCore.pyqtSignature("QTreeWidgetItem*, QTreeWidgetItem*")
	def on_treeWidget_AE_currentItemChanged( self, item1, item2): 
		#Clear
		self.lineEdit_AE_id.clear()
		self.lineEdit_Name.clear()
		self.textEdit_definition.clear()
		self.lineEdit_is_a.clear()
		self.tableWidget_attributes.clearContents()
  
		# Refresh ui: name AE_id and example
		if (self.treeWidget_AE.currentItem() != None and self.treeWidget_AE.currentItem()):
			self.lineEdit_AE_id.setText(str(self.treeWidget_AE.currentItem().AE_id))
			self.lineEdit_Name.setText(QtCore.QString.fromUtf8(self.treeWidget_AE.currentItem().name))
			if self.treeWidget_AE.currentItem().definition:
				self.textEdit_definition.setText( QtCore.QString.fromUtf8( self.treeWidget_AE.currentItem().definition))
		else:
			return    

		# Refresh is_a information: 
		if (self.treeWidget_AE.currentItem() != None and self.treeWidget_AE.currentItem()):
			self.lineEdit_is_a.setText(self.treeWidget_AE.currentItem().get_is_a())
		else:
			return 
		
		# Refresh the attributes list
		self.tableWidget_attributes.setSortingEnabled(False)  #Turne off sorting
		if (self.treeWidget_AE.currentItem() != None and self.treeWidget_AE.currentItem()):
			i=0
			list = self.treeWidget_AE.currentItem().getAttributes()        
			self.tableWidget_attributes.setRowCount(len(list))
			brush=QtGui.QBrush(QtGui.QColor(255,0, 255, 127),QtCore.Qt.Dense7Pattern)
			for attribute in list:
				# Colum Name:
				item0 = QtGui.QTableWidgetItem( QtCore.QString.fromUtf8( str( attribute.getName())),0)	
				item0.setFont(QtGui.QFont("Sans Serif", 9, QtGui.QFont.Bold))
				self.tableWidget_attributes.setItem(i,0,item0)
				# Colum Type:
				item1 = QtGui.QTableWidgetItem(QtCore.QString.fromUtf8(str(attribute.getType())),0)
				self.tableWidget_attributes.setItem(i,1,item1)
				# Colum Value:
				item2 = QtGui.QTableWidgetItem(QtCore.QString.fromUtf8(str(attribute.getValue())),0)
				self.tableWidget_attributes.setItem(i,2,item2)
				#Colum inheritance
				item3 = QtGui.QTableWidgetItem(QtCore.QString.fromUtf8(str(attribute.getAE().name)),0)
				self.tableWidget_attributes.setItem(i,3,item3)
				if attribute.getAE().name != self.treeWidget_AE.currentItem().name:
					item0.setBackground(brush)
					item1.setBackground(brush)
					item2.setBackground(brush)
					item3.setBackground(brush)
				else:
					item3 = QtGui.QTableWidgetItem(QtCore.QString.fromUtf8('- no one- '),0)
					self.tableWidget_attributes.setItem(i,3,item3)
				i=i+1
			
			self.tableWidget_attributes.resizeColumnsToContents()
			self.tableWidget_attributes.horizontalHeader().setStretchLastSection(True)




if __name__=="__main__":
	app=QtGui.QApplication(sys.argv) 

	# Check if the current working directory is the good one (optional)
#	workingDirEndBy = "mcf_browser/src"
#	currentPath = QtCore.QDir.currentPath().toUtf8()
#	begin = len( currentPath ) - len( workingDirEndBy )
#	end = len( currentPath )
#	if( currentPath[begin:end] != workingDirEndBy):
#		QtGui.QMessageBox.critical( None, QtCore.QString( "My Corporis Fabrica"), QtCore.QString( "You must start MyCorporisFabrica from the 'src' directory.\n\n- For Eclipse users: set your 'working directory' to \"%s\" in the tab Arguments of the application options ( Menu 'run->run configurations...')"%(workingDirEndBy)) )
#		exit( 1)
	
	#print os.getcwd()
	#print os.path.dirname(__file__)
	
	#Splashscreen
	#if sys.platform.startswith('linux'):
	#	pixmap = QtGui.QPixmap(":/icons/splashscreen.png")
	#if sys.platform.startswith('win'): 
	#	pixmap = QtGui.QPixmap(":\\icons\\splashscreen.png")
	pixmap = QtGui.QPixmap(":/icons/splashscreen_old.png")
	splash=QtGui.QSplashScreen(pixmap,QtCore.Qt.WindowStaysOnTopHint)
	splash.setMask(pixmap.mask()) # this is usefull if the splashscreen is not a regular rectangle...
	progressBar = QtGui.QProgressBar(splash)
	progressBar.setGeometry(splash.width()/6, 8*splash.height()/10, 4*splash.width()/6, splash.height()/10) 
	
	splash.show() 
	app.processEvents() 
	splash.showMessage(version_name, QtCore.Qt.AlignRight | QtCore.Qt.AlignBottom, QtCore.Qt.black)
	
	for i in range(0, 100):
		progressBar.setValue(i)
		if i == 14 :
			### without dialog login
			sqlserver = db.SQlserver('localhost', 'david', 'mariokart', 'write')
			splash.showMessage("Loading Database...Wait.", QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom, QtCore.Qt.black)
			window = myCFAppli(sqlserver)
			
			### with dialog login
			#ndia = Dialog_login(splash)
			#if ndia.exec_()==1:
			#	splash.showMessage("Loading Database...Wait.", QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom, QtCore.Qt.black)
			#	#window = myCFAppli(ndia.sqlserver)
			#	window = myCFAppli(ndia.sqlserver)
			#else:
			#	QtGui.QMessageBox.warning(splash,"myCF Error","No database connection. Application will turn off.")
			#	sys.exit (1)
		if i == 35 :
			splash.showMessage("Loading Main Window...", QtCore.Qt.AlignCenter | QtCore.Qt.AlignBottom, QtCore.Qt.black)
		# Do something which takes some time.
		t = time.time()
		while time.time() < t + 0.01:
			app.processEvents()

	
	window.show()
	window.setWindowTitle(QtGui.QApplication.translate("MainWindow", version_name, None, QtGui.QApplication.UnicodeUTF8))
	splash.finish(window)
	sys.exit(app.exec_())
	
###### May be use to creat log files
#import os, platform, logging
# 
#if platform.platform().startswith('Windows'):
#    logging_file = os.path.join(os.getenv('HOMEDRIVE'), os.getenv('HOMEPATH'), 'test.log')
#else:
#    logging_file = os.path.join(os.getenv('HOME'), 'test.log')
# 
#print("Logging à", logging_file)
# 
#logging.basicConfig(
#    level=logging.DEBUG,
#    format='%(asctime)s : %(levelname)s : %(message)s',
#    filename = logging_file,
#    filemode = 'w',
#)
# 
#logging.debug("début du programme")
#logging.info("en train de faire quelque chose")
#logging.warning("en train de mourir")
